--[[
 -- *名称:StraightTypeAnalyzer
 -- *描述:[XXXXXXXXX]
 -- *版权:Copyright © 2016-2018 深圳市三只小熊科技有限公司 版权所有
 -- *作者:Administrator
 -- *创建日期:2017-11-08
 -- *修改日期:2017-11-08
 ]]
local DdzSuitAnalyzer = require(basePath.."suit/ddzsuitanalyzer");
local StraightTypeAnalyzer = pokercore.class(DdzSuitAnalyzer,false);
local Cards = require(basePath .. "domain/cards");
--关键数量
StraightTypeAnalyzer.LIMIT_SIZE = 5 ;
local LIMIT_SIZE = 5 ; 
--关键数量
StraightTypeAnalyzer.LIMIT_SIZE_MAX = 12 ;
local LIMIT_SIZE_MAX = 12 ; 
--关键数量
StraightTypeAnalyzer.TUPLE_SIZE = 1 ;
local TUPLE_SIZE = 1 ; 
---
 -- [ctor 默认类的构造方法]
 -- @DateTime 2017-09-20
 -- @param     [description]
 -- @return    [description]
 --
function StraightTypeAnalyzer:ctor(...)
   StraightTypeAnalyzer.super.ctor(self,...) ;
end
---
 -- [dtor 默认类的销毁方法]
 -- @DateTime 2017-09-20
 -- @param     [description]
 -- @return    [description]
 --
function StraightTypeAnalyzer:dtor(...)
   StraightTypeAnalyzer.super.dtor(self,...) ;
end



--@Override
function StraightTypeAnalyzer:getSuitType()
   return DdzCardTypes.STRAIGHT
end

--@Override
function StraightTypeAnalyzer:doCheckRule(cards,term,result)
	if (result:getCardNum() >= StraightTypeAnalyzer.LIMIT_SIZE) and 
		(result:getCardNum() <= StraightTypeAnalyzer.LIMIT_SIZE_MAX) and 
		 (result:getCardNum() % StraightTypeAnalyzer.TUPLE_SIZE == 0) then
		 --都是癞子
		 if result:isAllCardLazi() then
		 	--print("StraightTypeAnalyzer:doCheckRule 1")
		 	return false ;
		 else
		 	-- 非赖部分有王
		 	if result:getNoneLaziValueCounter():hasJoker() then
		 		--print("StraightTypeAnalyzer:doCheckRule 2")
		 		return false ;
		 	end
		 	-- 非癞子部分有2 

		 	if result:getNoneLaziValueCounter():getValueCount(PokerGameConstant.NUMBER_2_VALUE) >0 then
		 		--print("StraightTypeAnalyzer:doCheckRule 3")
		 		return false ;
		 	end
		 	local allValues = result:getNoneLaziValueCounter():getAllValues();
		 	--全是单张
		 	for _,value in pairs(allValues) do
		 		if result:getNoneLaziValueCounter():getValueCount(value) > StraightTypeAnalyzer.TUPLE_SIZE then
		 			--print("StraightTypeAnalyzer:doCheckRule 4")
		 			return false ;
		 		end
		 	end
		 	--分析有几组牌，顺子中单张也算做一组 
		 	local tupleNum = result:getCardNum() / StraightTypeAnalyzer.TUPLE_SIZE ;
		 	-- 从A开始 遍历寻找所有可能的顺子
		 	local valueTemp = PokerGameConstant.NUMBER_2_VALUE - 1 ;
		 	while valueTemp >= PokerGameConstant.NUMBER_3_VALUE + (tupleNum - 1) do
		 		if DdzTypeUtil.ensureStaight(valueTemp, StraightTypeAnalyzer.TUPLE_SIZE, StraightTypeAnalyzer.TUPLE_SIZE, cards, term, result) then
		 			--print("StraightTypeAnalyzer:doCheckRule",true);
		 			return true ;
		 		end
		 		valueTemp = valueTemp - 1  ;
		 	end
		 	--print("StraightTypeAnalyzer:doCheckRule 5")
		 	return false ;
		 end
	else
		--print("StraightTypeAnalyzer:doCheckRule 6")
		return false ;
	end
end

--@Override
function StraightTypeAnalyzer:doAnalysizeLaizi(cards,term,onlyMaxValue)
	local cardsResult = {};
	local result = cards:getResult();
	local laiziCardList = cards:subList(result:getCardNum() - result:getLaziCardNum()+1, result:getCardNum())
	--分析有几组牌，顺子中单张也算做一组
	local tupleNum = result:getCardNum() / StraightTypeAnalyzer.TUPLE_SIZE; 
	--遍历寻找所有可能的顺子
	local beginValueTemp = PokerGameConstant.NUMBER_2_VALUE - 1 ;
	while beginValueTemp >= (PokerGameConstant.NUMBER_3_VALUE + tupleNum - 1) do
		if DdzTypeUtil.ensureStaight(beginValueTemp,StraightTypeAnalyzer.TUPLE_SIZE, StraightTypeAnalyzer.TUPLE_SIZE,cards,term,result) then
			local laiziCardIndex = 0 ;
			local valueTemp = beginValueTemp ;
			while valueTemp > (beginValueTemp - tupleNum) do
				local valueTempNum = result:getNoneLaziValueCounter():getValueCount(valueTemp);
				local needLaiziCardNum = StraightTypeAnalyzer.TUPLE_SIZE - valueTempNum ;
				for i=1,needLaiziCardNum do
					laiziCardIndex = laiziCardIndex + 1;
					laiziCardList[laiziCardIndex]:changeCard(valueTemp);
				end	
				valueTemp = valueTemp - 1 ;
			end
			for k,v in ipairs(laiziCardList) do
    		 --print("laiziCardList->",v);
  			end
			local cardsCopy = cards:clone();	
			--print("################",cards);	
			--print("****************");
			self:analysize(cardsCopy,term);
			table.insert(cardsResult,cardsCopy:clone());
			if onlyMaxValue then
				break ;
			end
		end
		beginValueTemp = beginValueTemp - 1 ;
	end
	return cardsResult ;
end



--提牌算法

--@Override
function StraightTypeAnalyzer:containsPossibleCards(handCards,term) 
	local result = handCards:getResult();
	if (result:getCardNum() - result:getJokerCardNum() < LIMIT_SIZE) then --// 张数不够
		--print("StraightTypeAnalyzer:containsPossibleCards 1");
		return false;
	end
	--// 遍历寻找所有可能的顺子
	for beginValueTemp = PokerGameConstant.NUMBER_2_VALUE - 1 --// 从A开始
			,PokerGameConstant.NUMBER_3_VALUE + LIMIT_SIZE / TUPLE_SIZE - 1, -1 do
		if (DdzTypeUtil.ensureTupleStaightDesc(
				beginValueTemp, LIMIT_SIZE / TUPLE_SIZE, TUPLE_SIZE, handCards, term, result)) then --// 最低标准顺一下
			return true;
		end
	end
	--print("StraightTypeAnalyzer:containsPossibleCards 2");
	return false;
end
	
--/** 最多使用癞子的数量 */
local MAX_USE_LAIZI_CARD_NUM = 8;

--/** 防重复判定的比例值 参照 int key = tupleNum * TUPLE_WEIGHT + beginValueTemp; */
local TUPLE_WEIGHT = 1000000;

--/** 癞子权重，区分癞子变成的5 和 原本就是5 */
local LAIZI_WEIGHT = 1000;
	
--@Override
function StraightTypeAnalyzer:doListPossibleCards(handCards,term)
	--dump(handCards,"StraightTypeAnalyzer:doListPossibleCards handCards");
	local cardsResult = {};
	--// 非癞子部分
	local result = handCards:getResult();
	local noneLaiziCardList = handCards:subList(1, result:getNoneCardNum());
	local noneLaiziCards = DdzTypeUtil.createCardsCopy(noneLaiziCardList);
	noneLaiziCards:setResult(handCards:getResult():clone());
	--// 癞子部分
 	local laiziCardList = handCards:subList(result:getNoneCardNum()+1, result:getCardNum());
 	--dump(laiziCardList,"laiziCardList->");
	local laiziCards = DdzTypeUtil.createCardsCopy(laiziCardList);
	laiziCards:setResult(handCards:getResult():clone());
	--dump(laiziCards,"laiziCards->");
	local laiziCardNum = result:getLaziCardNum();
	local maxUseLaiziCardNum = MAX_USE_LAIZI_CARD_NUM < laiziCardNum and MAX_USE_LAIZI_CARD_NUM or laiziCardNum;
	--print("maxUseLaiziCardNum",maxUseLaiziCardNum);
	local exsitKeys = {};
	for useLaiziCardNum = 0,maxUseLaiziCardNum do
		local useLaiziCardList = DdzTypeUtil.cloneSublistedCards(laiziCards, 1, useLaiziCardNum); --// 补癞子
		--dump(useLaiziCardList,"useLaiziCardList");
		table.reverse(useLaiziCardList); --// 因为这里是倒序赋值，避免 把点数小的癞子牌赋成大值又把点数大的癞子牌赋成小值 的疑惑
		--dump(useLaiziCardList,"useLaiziCardList2");
		local modelCards = DdzTypeUtil.cloneCardsAndAddCardList(noneLaiziCards, useLaiziCardList);-- // 常规牌补上癞子
		--dump(modelCards,"modelCards");
		local modelResult = modelCards:getResult();
		modelResult:collectNumber(modelCards, term); --// 重新获取下点值
		--// 从5顺开始找 10.JQK1 找完找 9.10.J.Q.K.1 在找 8.9.10.J.Q.K.1 
			--// 从5顺开始找 10.JQK1 找完找 9.10.J.Q.K.1 在找 8.9.10.J.Q.K.1 
		for tupleNum = LIMIT_SIZE / TUPLE_SIZE, modelResult:getCardNum() / TUPLE_SIZE do
			local partLenResult = {} --// 部分长度的结果 
			--// 遍历寻找所有可能的顺子  10.J.Q.K.1 找完找 9.10.J.Q.K 在找 8.9.10.J.Q
			for beginValueTemp = PokerGameConstant.NUMBER_2_VALUE - 1 --// 从A开始
					, PokerGameConstant.NUMBER_3_VALUE + tupleNum - 1,-1 do
				local laiziCardIndex = 0;
				local straightKey = tupleNum * TUPLE_WEIGHT + beginValueTemp;
				if (not exsitKeys[straightKey] --// 每种顺子仅判定一次
						and DdzTypeUtil.ensureTupleStaightDesc(beginValueTemp, tupleNum, TUPLE_SIZE, modelCards, term, modelResult)) then
					--print("jin lai le ");
					exsitKeys[straightKey] = true;
					local straightCards = pokercore.new(Cards);
					--print("beginValueTemp->",beginValueTemp);
					--print("endTemp->",beginValueTemp - tupleNum+1);
					for valueTemp = beginValueTemp,beginValueTemp - tupleNum+1,-1 do -- // 从大到小
						local valueTempNum = modelResult:getNoneLaziValueCounter():getValueCount(valueTemp);
						if (valueTempNum >= TUPLE_SIZE) then
							--print("TUPLE_SIZE->",TUPLE_SIZE);
							--print("valueTempNum->",valueTemp);
							local tempCards = DdzTypeUtil.cloneObtainedCards(modelCards, valueTemp, TUPLE_SIZE)
							--dump(tempCards,"tempCards");
							straightCards:addCards(tempCards);
						else 
							--print("TUPLE_SIZE valueTempNum->",valueTempNum);
							straightCards:addCards(DdzTypeUtil.cloneObtainedCards(modelCards, valueTemp, valueTempNum));
							local needLaiziCardNum = TUPLE_SIZE - valueTempNum;
							for  i = 1, needLaiziCardNum do --// 用了癞子才加上，不会任意补全（癞子不会去替代玩家已有的顺子中的元素）
								laiziCardIndex = laiziCardIndex + 1 ;
								local laiziCardCopy = useLaiziCardList[laiziCardIndex]:clone();
								laiziCardCopy:changeCard(valueTemp);
								straightCards:addCard(laiziCardCopy);
							end
						end
					end
					--dump(straightCards,"straightCards");
					local laiziNumKey = 0;
					for _,card in ipairs(straightCards:getCardList()) do
						if card:isLazi() then -- // 癞子权重，区分癞子变成的5 和 原本就是5
							laiziNumKey = laiziNumKey + LAIZI_WEIGHT + card:getValue();
						else 
							laiziNumKey = laiziNumKey + card:getValue();
						end
					end
					if (not exsitKeys[laiziNumKey] -- // 保证癞子不会变形 比如  **10** 和 10**** 只出现一次最大的提牌
							and self:match(straightCards, term)) then
						exsitKeys[laiziNumKey] = true ;
						--dump(straightCards,"ddddddddddddddddddddd");
						self:analysize(straightCards, term);
						table.insert(partLenResult,1,straightCards); --// 这里倒序加入，保证从小到大   
					end
				end
			end
			--dump(partLenResult,"partLenResult");
			table.addAll(cardsResult,partLenResult);
		end
	end
	--dump(cardsResult,"StraightTypeAnalyzer:doListPossibleCards");
	return cardsResult;
end


return StraightTypeAnalyzer;

